//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
void CALLBACK taskList(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
    if(flagWriteConfig1 == true)
    {
        if(canConfigCounter <= 4)
        {
            //flagWriteConfig1 = true;
            Form1->sendList();
        }
        else
        {
            flagWriteConfig1 = false;
            canConfigCounter = 0;
            return;
        }

    }
    else if(flagWriteCode1 == true)
    {
        if(variantCounter <= 2)
        {
            //flagWriteCode1 = true;
            Form1->sendList();
        }
        else
        {
            flagWriteCode1 = false;
            variantCounter = 0;
            return;
        }
    }
}                                       
//---------------------------------------------------------------------------
void __fastcall timerStart(UINT ms_time_val)
{
    //timeBeginPeriod(5);
    g_TIMEID = timeSetEvent(ms_time_val, 5, taskList,0,TIME_ONESHOT);
}
//---------------------------------------------------------------------------
void End_timer(void)
{
     timeKillEvent(g_TIMEID);

//   timeEndPeriod(5);
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
void __fastcall TForm1::messageTranceiver(TWMCanLib& Message)
{
    int stat;
    long id;
    unsigned char RxData[8] = {0x00};
    unsigned int dlc, flags;
    unsigned long timestamp;
    while(canRead(Handle1, &id, RxData, &dlc, &flags, &timestamp) == canOK)
    {
        CanMessage messageRx= {id,
                               dlc,
                               RxData[0], RxData[1], RxData[2], RxData[3], RxData[4], RxData[5], RxData[6], RxData[7]};

        if (dlc > 0)
        {
            if((RxData[0] == 0x02) && (RxData[1] == 0x7E)) //ban the response to testerpresent
            {
                if((CheckBox4->Enabled == true) && (CheckBox4->Checked == true))
                {
                    memo1Display(&messageRx, 1);
                    continue;
                }
            }
            else if((RxData[1] == 0x7F) && (RxData[2] == 0x3E)) //ban the response to testerpresent
            {
                if((CheckBox4->Enabled == true) && (CheckBox4->Checked == true))
                {
                    memo1Display(&messageRx, 1);
                    continue;
                }
            }
            else
            {
                memo1Display(&messageRx, 1);
            }
        }
        //if failed to security access
        if ((RxData[0] == 0x03) && (RxData[1] == 0x7F ) && (RxData[2] == 0x27))
        {
            clearFlag();
        }
        else if ((messageRx.data[0] & 0xF0) == 0x10)//flowcontrol
        {
            CanMessage messageTx = {0x740,
                                    0x3,
                                    0x30, 0x00, 0x00};
            messageTx.data[1] = ("0x" + ComboBox8->Text).ToInt();
            stat = canWrite(Handle1, messageTx.id, messageTx.data, messageTx.dlc, 0);
            if (stat == canOK) memo1Display(&messageTx,0);
            flowControlLength = (int)ceil((floor)((messageRx.data[0] & 0x0F) * 0x0100 + messageRx.data[1] - 0x06) / 7);
            flowControlRest = ("0x" + ComboBox8->Text).ToInt();
        }
        else if ((messageRx.data[0] & 0xF0) == 0x20) //in flow control
        {
            if(flowControlRest == 0)
            {
                continue;
            }
            if(flowControlLength != 1)
            {
                flowControlLength--;
                if(flowControlRest != 1)
                {
                    flowControlRest--;
                }
                else
                {
                    CanMessage messageTx = {0x740,
                                            0x3,
                                            0x30, 0x00, 0x00};
                    messageTx.data[1] = ("0x" + ComboBox8->Text).ToInt();
                    stat = canWrite(Handle1, messageTx.id, messageTx.data, messageTx.dlc, 0);
                    if (stat == canOK) memo1Display(&messageTx,0);
                    flowControlRest = ("0x" + ComboBox8->Text).ToInt();
                }
            }
            else
            {
                stat = 0;
            }
        }
        else if (messageRx.data[0] == 0x30)
        {
            if (flagNeedConfig1 == true) flagWriteConfig1 = true;
            else if (flagNeedCode1 == true) flagWriteCode1 = true;
        }

        else
        {
            switch (RxData[1])
            {

                case 0x67:
                     if ((RxData[2] == 0x03) && (RxData[3]|RxData[4] != 0x00))
                     {
                         Word seed, calKey;
                         //calKey = 0xF480;
                         seed = (RxData[3]<<8) + RxData[4];
                         calKey = calcKey(seed);
                         CanMessage messageTx = {0x740,
                                                 0x5,
                                                 0x04, 0x27, 0x04, calKey/0x100, calKey%0x100};
                         stat = canWrite(Handle1, messageTx.id, messageTx.data, messageTx.dlc, 0);
                               if (stat == canOK) memo1Display(&messageTx,0);
                               return;/***need RETURN after WRITE in WMCanLib() in case of sendList() malfunc***/
                     }
                     else break;
                     default: break;
            }
        }
    }
        sendList();

}
//---------------------------------------------------------------------------
void __fastcall TForm1::sendList()
{
    int stat;
    if (flagStratDiag == true)
    {
        flagStratDiag = false;
        CanMessage messageTx = {0x740,
                                0x3,
                                0x02, 0x10};
        switch(ComboBox1->ItemIndex)
        {
            case 0: messageTx.data[2] = 0x01; break;
            case 1: messageTx.data[2] = 0x02; break;
            case 2: messageTx.data[2] = 0x03; break;
        }

        stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
        if (stat == canOK)
        {
            Memo1->Lines->Add(">>>>>0" + IntToStr(messageTx.data[2])+" mode<<<<<");
            memo1Display(&messageTx, 0);
        }
        return;
    }
    if (flagStrat03Mode == true)
    {
        flagStrat03Mode = false;
        CanMessage messageTx = {0x740,
                                0x3,
                                0x02, 0x10, 0x03};
        stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
        if (stat == canOK)
        {
            Memo1->Lines->Add(">>>>>03 mode<<<<<");
            memo1Display(&messageTx, 0);
        }
        return;
    }
    if (flagSecAccess == true)
    {
        flagSecAccess = false;     
        CanMessage messageTx = {0x740,
                                0x3,
                                0x02, 0x27, 0x03};
        stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
        if (stat == canOK)
        {
            Memo1->Lines->Add(">>>>>security access<<<<<");
            memo1Display(&messageTx, 0);
        }
        return;
    }
    if (flagReset == true)
    {
        flagReset = false;
        CanMessage messageTx = {0x740,
                                0x3,
                                0x02, 0x11, 0x01};
        stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
        if (stat == canOK)
        {
            Memo1->Lines->Add(">>>>>ECU reset<<<<<");
            memo1Display(&messageTx, 0);
        }
        return;
    }
    if (flagStartRoutine == true)
    {
        flagStartRoutine = false;
        CanMessage messageTx = {0x740,
                                0x5,
                                0x04, 0x31, 0x01, 0x61};
        switch(ComboBox2->ItemIndex)
        {
            case 0: messageTx.data[4] = 0x40; break;
            case 1: messageTx.data[4] = 0x41; break;
            case 2: messageTx.dlc = 0x6;
                    messageTx.data[0] = 0x05;
                    messageTx.data[4] = 0x42;
                    messageTx.data[5] = 0x01;
                    break;//ship mode
            case 3: messageTx.dlc = 0x6;
                    messageTx.data[0] = 0x05;
                    messageTx.data[4] = 0x42;
                    messageTx.data[5] = 0x02;
                    break;//normal mode
            case 4: messageTx.data[3] = 0xFF;
                    messageTx.data[4] = 0xFF;
                    break;//one key battery saver
        }

        stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
        if (stat == canOK)
        {
            Memo1->Lines->Add(">>>>>start routine<<<<<");
            memo1Display(&messageTx, 0);
        }
        return;
    }
    if (flagStopRoutine == true)
    {
        flagStopRoutine = false;
        CanMessage messageTx = {0x740,
                                0x5,
                                0x04, 0x31, 0x02, 0x61};
        switch(ComboBox2->ItemIndex)
        {
            case 0: messageTx.data[4] = 0x40; break;
            case 1: messageTx.data[4] = 0x41; break;
            case 2: messageTx.dlc = 0x6;
                    messageTx.data[0] = 0x05;
                    messageTx.data[4] = 0x42;
                    messageTx.data[5] = 0x01;
                    break;//ship mode
            case 3: messageTx.dlc = 0x6;
                    messageTx.data[0] = 0x05;
                    messageTx.data[4] = 0x42;
                    messageTx.data[5] = 0x02;
                    break;//normal mode
        }
        stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
        if (stat == canOK)
        {
            Memo1->Lines->Add(">>>>>stop routine<<<<<");
            memo1Display(&messageTx, 0);
        }
        return;
    }
    if (flagRoutineResult == true)
    {
        flagRoutineResult = false;
        CanMessage messageTx = {0x740,
                                0x5,
                                0x04, 0x31, 0x03, 0x61};
        switch(ComboBox2->ItemIndex)
        {
            case 0: messageTx.data[4] = 0x40; break;
            case 1: messageTx.data[4] = 0x41; break;
            case 2: messageTx.dlc = 0x6;
                    messageTx.data[0] = 0x05;
                    messageTx.data[4] = 0x42;
                    messageTx.data[5] = 0x01;
                    break;//ship mode
            case 3: messageTx.dlc = 0x6;
                    messageTx.data[0] = 0x05;
                    messageTx.data[4] = 0x42;
                    messageTx.data[5] = 0x02;
                    break;//normal mode
        }
        stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
        if (stat == canOK)
        {
            Memo1->Lines->Add(">>>>>routine result<<<<<");
            memo1Display(&messageTx, 0);
        }
        return;
    }
    if (flagStatusRead == true)
    {
        flagStatusRead = false;
        CanMessage messageTx = {0x740,
                                0x4,
                                0x03, 0x22};
        if((ComboBox3->ItemIndex == -1) && (ComboBox4->ItemIndex == -1)) return;
        switch(ComboBox3->ItemIndex)
        {
            case -1: break;
            case  0: messageTx.data[2] = 0x60,
                     messageTx.data[3] = 0x00; break;
            case  1: messageTx.data[2] = 0x60,
                     messageTx.data[3] = 0x01; break;
            case  2: messageTx.data[2] = 0xF1,
                     messageTx.data[3] = 0x87; break;
            case  3: messageTx.data[2] = 0xF1,
                     messageTx.data[3] = 0x8A; break;
            case  4: messageTx.data[2] = 0xF1,
                     messageTx.data[3] = 0x91; break;
            case  5: messageTx.data[2] = 0xF1,
                     messageTx.data[3] = 0x94; break;
        }
        switch(ComboBox4->ItemIndex)
        {
            case -1: break;
            case  0: messageTx.data[2] = 0x60,
                     messageTx.data[3] = 0x02; break;
            case  1: messageTx.data[2] = 0x60,
                     messageTx.data[3] = 0x03; break;
            case  2: messageTx.data[2] = 0x60,
                     messageTx.data[3] = 0x04; break;
            case  3: messageTx.data[2] = 0x60,
                     messageTx.data[3] = 0x05; break;
            case  4: messageTx.data[2] = 0x60,
                     messageTx.data[3] = 0x06; break;
            case  5: messageTx.data[2] = 0x60,
                     messageTx.data[3] = 0x07; break;
            case  6: messageTx.data[2] = 0x60,
                     messageTx.data[3] = 0x0C; break;
            case  7: messageTx.data[2] = 0x60,
                     messageTx.data[3] = 0x0E; break;
            case  8: messageTx.data[2] = 0x60,
                     messageTx.data[3] = 0x0F; break;
            case  9: messageTx.data[2] = 0x60,
                     messageTx.data[3] = 0x10; break;
            case 10: messageTx.data[2] = 0x60,
                     messageTx.data[3] = 0x11; break;
            case 11: messageTx.data[2] = 0x60,
                     messageTx.data[3] = 0x13; break;
        }
        stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
        if (stat == canOK)
        {
            Memo1->Lines->Add(">>>>>read status<<<<<");
            memo1Display(&messageTx, 0);
        }
        return;
    }
    if (flagReadDTC == true)
    {
        flagReadDTC = false;
        CanMessage messageTx = {0x740,
                                0x4,
                                0x03, 0x19, 0x02};
        messageTx.data[3] = ("0x" + Edit1->Text).ToInt();

        stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
        if (stat == canOK)
        {
            Memo1->Lines->Add(">>>>>read DTC<<<<<");
            memo1Display(&messageTx, 0);
        }
        return;
    }
    if (flagSurported == true)
    {
        flagSurported = false;
        CanMessage messageTx = {0x740,
                                0x3,
                                0x02, 0x19, 0x0A};
        stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
        if (stat == canOK)
        {
            Memo1->Lines->Add(">>>>>read supported DTC<<<<<");
            memo1Display(&messageTx, 0);
        }
        return;
    }
    if (flagClearDTC == true)
    {
        flagClearDTC = false;
        CanMessage messageTx = {0x740,
                                0x5,
                                0x04, 0x14, 0xFF, 0xFF, 0xFF};
        stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
        if (stat == canOK)
        {
            Memo1->Lines->Add(">>>>>clear DTC<<<<<");
            memo1Display(&messageTx, 0);
        }
        return;
    }
    if (flagCommControl == true)
    {
        flagCommControl = false;
        CanMessage messageTx = {0x740,
                                0x4,
                                0x03, 0x28, 0x00, 0x03};
        if(ComboBox6->ItemIndex == 1) messageTx.data[2] = 0x03;
        stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
        if (stat == canOK)
        {
            Memo1->Lines->Add(">>>>>communication control<<<<<");
            memo1Display(&messageTx, 0);
        }
        return;
    }
    if (flagDTCSetting == true)
    {
        flagDTCSetting = false;
        CanMessage messageTx = {0x740,
                                0x3,
                                0x02, 0x85, 0x01};
        if(ComboBox7->ItemIndex == 1) messageTx.data[2] = 02;
        stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
        if (stat == canOK)
        {
            Memo1->Lines->Add(">>>>>DTC setting<<<<<");
            memo1Display(&messageTx, 0);
        }
        return;
    }
    if (flagReadConfig == true)
    {
        flagReadConfig = false;
        if(PageControl1->ActivePage == TabSheet1)
        {
            CanMessage messageTx = {0x740,
                                    0x4,
                                    0x03, 0x22, 0x60, 0xFF};
            stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
            if (stat == canOK)
            {
                Memo1->Lines->Add(">>>>>read can config<<<<<");
                memo1Display(&messageTx, 0);
            }
            return;
        }
        else if(PageControl1->ActivePage == TabSheet2)
        {
            CanMessage messageTx = {0x740,
                                    0x4,
                                    0x03, 0x22, 0xF1, 0xA1};
            stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
            if (stat == canOK)
            {
                Memo1->Lines->Add(">>>>>read variant code<<<<<");
                memo1Display(&messageTx, 0);
            }
            return;
        }
    }
    if (flagWriteConfig == true)
    {
        flagWriteConfig = false;
        if (PageControl1->ActivePage == TabSheet1) //write can config
        {
            strcpy(canConfig, (Edit2->Text).c_str());
            CanMessage messageTx = {0x740,
                                    0x8,
                                    0x10, 0x23, 0x2E, 0x60, 0xFF};
            messageTx.data[5] = ("0x" + (AnsiString)canConfig[0] + (AnsiString)canConfig[1]).ToInt();
            messageTx.data[6] = ("0x" + (AnsiString)canConfig[2] + (AnsiString)canConfig[3]).ToInt();
            messageTx.data[7] = ("0x" + (AnsiString)canConfig[4] + (AnsiString)canConfig[5]).ToInt();
            stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
            if (stat == canOK)
            {
                Memo1->Lines->Add(">>>>>write can config<<<<<");
                memo1Display(&messageTx, 0);
                flagNeedConfig1 = true;
            }
            return;
        }
        else if (PageControl1->ActivePage == TabSheet2) //write variant code
        {
            strcpy(variantCode, (Edit10->Text).c_str());
            CanMessage messageTx = {0x740,
                                    0x8,
                                    0x10, 0x1B, 0x2E, 0xF1, 0xA1};
            messageTx.data[5] = ("0x" + (AnsiString)variantCode[0] + (AnsiString)variantCode[1]).ToInt();
            messageTx.data[6] = ("0x" + (AnsiString)variantCode[2] + (AnsiString)variantCode[3]).ToInt();
            messageTx.data[7] = ("0x" + (AnsiString)variantCode[4] + (AnsiString)variantCode[5]).ToInt();
            stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
            if (stat == canOK)
            {
                Memo1->Lines->Add(">>>>>write variant code<<<<<");
                memo1Display(&messageTx, 0);
                flagNeedCode1 = true;
            }
            return;
        }
    }
    if (flagWriteConfig1 == true)//write the rest(29 bytes) of can configuration(32 bytes)
    {
        //flagWriteConfig1 = false;
        int stat, d;
        if(canConfigCounter == 0)
        {
            j = 6;
            i = 0;
        }
        CanMessage messageTx = {0x740,
                                0x8};
        if(i <= 4)
        {
            //while SN exceeds F should re-start from 0
            messageTx.data[0] = ("0x" + IntToStr(20 + (i + 1) % 16)).ToInt();
            for(d = 1; d <= 7; d++)
            {
                if(canConfig[j] == '\0') canConfig[j] = '0';       // avoid to the error of 0x'\0'
                if(canConfig[j+1] == '\0') canConfig[j+1] = '0';   //
                messageTx.data[d] = ("0x" + (AnsiString)canConfig[j] + (AnsiString)canConfig[j+1]).ToInt();
                j += 2;
            }
            i++;
            stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
            if (stat == canOK) memo1Display(&messageTx, 0);
        }
        timerStart(20);//delay for the next CF
        canConfigCounter++;
        return;
    }
    if (flagWriteCode1 == true)//write the rest(21 bytes) of variant data(24 bytes)
    {
        //flagWriteCode1 = false;
        int stat, d;
        if(variantCounter == 0)
        {
            j = 6;
            i = 0;
        }
        CanMessage messageTx = {0x740,
                                0x8};
        if(i <= 2)
        {
            //while SN exceeds F should re-start from 0
            messageTx.data[0] = ("0x" + IntToStr(20 + (i + 1) % 16)).ToInt();
            for(d = 1; d <= 7; d++)                                                                 
            {
                if(canConfig[j] == '\0') canConfig[j] = '0';       // avoid to the error of 0x'\0'
                if(canConfig[j+1] == '\0') canConfig[j+1] = '0';   //
                messageTx.data[d] = ("0x" + (AnsiString)variantCode[j] + (AnsiString)variantCode[j+1]).ToInt();
                j += 2;
            }
            i++;
            stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
            if (stat == canOK) memo1Display(&messageTx, 0);
        }
        timerStart(20);//delay for the next CF
        variantCounter++;
        return;
    }
    if ((flagCtrlON == true) || (flagCtrlOFF == true) || (flagReturnECU == true))
    {
        CanMessage messageTx = {0x740,
                                0x6,
                                0x05, 0x2F, 0x61, 0x00, 0x03};
        if      (RadioButton1->Checked == true)
                {
                    messageTx.data[3] = 0x00;
                }
        else if (RadioButton2->Checked == true)
                {
                    messageTx.data[3] = 0x01;
                }
        else if (RadioButton3->Checked == true)
                {
                    messageTx.data[3] = 0x02;
                }
        else if (RadioButton4->Checked == true)
                {
                    messageTx.data[3] = 0x03;
                }
        else if (RadioButton5->Checked == true)
                {
                    messageTx.data[3] = 0x04;
                }
        else if (RadioButton6->Checked == true)
                {
                    messageTx.data[3] = 0x05;
                }
        else if (RadioButton7->Checked == true)
                {
                    messageTx.data[3] = 0x06;
                }
        else if (RadioButton8->Checked == true)
                {
                    messageTx.data[3] = 0x09;
                }
        else if (RadioButton9->Checked == true)
                {
                    messageTx.data[3] = 0x0A;
                }
        else if (RadioButton10->Checked == true)
                {
                    messageTx.data[3] = 0x0B;
                }
        else if (RadioButton11->Checked == true)
                {
                    messageTx.data[3] = 0x0C;
                }
        else if (RadioButton12->Checked == true)
                {
                    messageTx.data[3] = 0x10;
                }
        else if (RadioButton13->Checked == true)
                {
                    messageTx.data[3] = 0x11;
                }
        else if (RadioButton14->Checked == true)
                {
                    messageTx.data[3] = 0x12;
                }
        else if (RadioButton15->Checked == true)
                {
                    messageTx.data[3] = 0x13;
                }
        else if (RadioButton16->Checked == true)
                {
                    messageTx.data[3] = 0x14;
                }
        else if (RadioButton17->Checked == true)
                {
                    messageTx.data[3] = 0x20;
                }
        else if (RadioButton18->Checked == true)
                {
                    messageTx.data[3] = 0x21;
                }
        else if (RadioButton19->Checked == true)
                {
                    messageTx.data[3] = 0x22;
                }
        else if (RadioButton20->Checked == true)
                {
                    messageTx.data[3] = 0x23;
                }
        else if (RadioButton21->Checked == true)
                {
                    messageTx.data[3] = 0x24;
                }
        else if (RadioButton22->Checked == true)
                {
                    messageTx.data[3] = 0x25;
                }
        else if (RadioButton23->Checked == true)
                {
                    messageTx.data[3] = 0x30;
                }
        else if (RadioButton24->Checked == true)
                {
                    messageTx.data[3] = 0x31;
                }
        else if (RadioButton25->Checked == true)
                {
                    messageTx.data[3] = 0x32;
                }
        else if (RadioButton26->Checked == true)
                {
                    messageTx.data[3] = 0x33;
                }
        else if (RadioButton27->Checked == true)
                {
                    messageTx.data[3] = 0x34;
                }
        else if (RadioButton28->Checked == true)
                {
                    messageTx.data[3] = 0x35;
                }

        if      (flagCtrlON == true)
        {
            flagCtrlON = false;
//          messageTx.data[4] = 0x03;
            messageTx.data[5] = 0x01;
        }
        else if (flagCtrlOFF == true)
        {
            flagCtrlOFF = false;
//          messageTx.data[4] = 0x03;
            messageTx.data[5] = 0x02;
        }
        else if (flagReturnECU == true)
        {
            flagReturnECU = false;
            messageTx.dlc = 0x5;
            messageTx.data[0] = 0x04;
            messageTx.data[4] = 0x00;
        }
        stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
        if (stat == canOK)
        {
            Memo1->Lines->Add(">>>>>I/O control<<<<<");
            memo1Display(&messageTx, 0);
        }
        return;
    }

}
//---------------------------------------------------------------------------



//---------------------------------------------------------------------------
void __fastcall TForm1::clearFlag()
{
    flagStratDiag = false;
    flagStrat03Mode = false;
    flagSecAccess = false;
    flagReset = false;
    flagStartRoutine = false;
    flagStopRoutine = false;
    flagRoutineResult = false;
    flagStatusRead = false;
    flagReadDTC = false;
    flagSurported = false;
    flagClearDTC = false;
    flagReadConfig = false;
    flagWriteConfig = false;
    flagWriteConfig1 = false;
    flagReadViriantCode = false;
    flagWriteViriantCode = false;
    flagCtrlON = false;
    flagCtrlOFF = false;
    flagReturnECU = false;
    flagNeedConfig1 = false;
    flagNeedCode1 = false;
    flagWriteCode1 = false;
    flagCommControl = false;
    flagDTCSetting = false;
    flagInFlowControl = false; 
}
//---------------------------------------------------------------------------
/* Function Name:Word calcKey(Word seed)
* Description: Calculate key to a given seed.
* Param: seed - Seed to which the key has to be calculated
* Return:Word - Calculated key*/
Word __fastcall TForm1::calcKey(Word seed)
{
#define TOPBIT 0x8000
#define POLYNOM_1 0x8408
#define POLYNOM_2 0x8025
#define BITMASK 0x0080
#define INITIAL_REMINDER 0xFFFE
#define MSG_LEN 2 /* seed length in bytes */
Byte bSeed[2];
Word remainder;
Byte n;
Byte i;
bSeed[0] = (Byte)(seed >> 8); /* MSB */
bSeed[1] = (Byte)seed; /* LSB */
remainder = INITIAL_REMINDER;
    for (n = 0; n < MSG_LEN; n++)
    {
    /* Bring the next byte into the remainder. */
    remainder ^= ((bSeed[n]) << 8);
    /* Perform modulo-2 division, a bit at a time. */
        for (i = 0; i < 8; i++)
        {
        /* Try to divide the current data bit. */
          if (remainder & TOPBIT)
          {
            if(remainder & BITMASK)
            {
              remainder = (remainder << 1) ^ POLYNOM_1;
            }
            else
            {
              remainder = (remainder << 1) ^ POLYNOM_2;
            }
         }
         else
         {
           remainder = (remainder << 1);
         }
       }
    }
/* The final remainder is the key */
return remainder;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::memo1Display(CanMessage* messageTx, int flagRxTx)//timestamp = canReadTimer(Handle1);
{
    AnsiString flagString;
    AnsiString data;
    unsigned int i;
    if (flagRxTx == 0)
        flagString = "Tx: ";
    else if (flagRxTx ==1)
        flagString = "Rx: ";
    else flagString = "  : ";
    for(i = 0;i <= (messageTx->dlc - 1);i++)
    {
        data += IntToHex(messageTx->data[i], 2) + "  ";

    }
    while(i <= 7)
    {
        data += "      ";
        i++; 
    }

    Form1->Memo1->Lines->Add(flagString + IntToHex((int)(messageTx->id), 3) + "  "
                                        + IntToHex((int)(messageTx->dlc), 1) + "  "
                                        + data
                                        /*+ Format("%20.3f  T", ARRAYOFCONST(((float)(canReadTimer(Handle1))/1000)))*/);


}

//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
    int i, chanCount;
    char name[64];

    canInitializeLibrary();
    if (canGetNumberOfChannels(&chanCount) < 0) return;

    for (i=0; i<chanCount; i++)
    {
        canGetChannelData(i, canCHANNELDATA_CHANNEL_NAME, name, sizeof(name));
        ComboBox5->Items->Add((AnsiString)name);
    }
    Handle1 = -1;
    ComboBox5->ItemIndex = 0;

    PageControl1Change(PageControl1);
}
//---------------------------------------------------------------------------



__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button16Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    if(Button16->Caption == "Bus ON")
    {
        ComboBox5->Enabled = false;
        canBusOff(Handle1);
        int stat = -1;
        Handle1 = canOpenChannel(ComboBox5->ItemIndex, canWANT_VIRTUAL);
        if (Handle1 < 0)
        {
            MessageDlg("Can't open can channel.", mtError, TMsgDlgButtons()<<mbOK, 0);
            ComboBox5->Enabled = true;
            return;
        }
        stat = canSetBusParams(Handle1, BAUD_500K, 0, 0, 0, 0, 0);
        if (stat < 0)
        {
            MessageDlg("Can't set baud rate.", mtError, TMsgDlgButtons()<<mbOK, 0);
            ComboBox5->Enabled = true;
            return;
        }
        //Filter for 750
        canAccept(Handle1, 0x750, canFILTER_SET_CODE_STD);
        canAccept(Handle1, 0x7FF, canFILTER_SET_MASK_STD);
        canSetNotify(Handle1, Handle, canNOTIFY_RX);
        canBusOn(Handle1);
        Button16->Caption = "Bus OFF";
        Timer1->Enabled = true;//test present timer
    }
    else if (Button16->Caption =="Bus OFF")
    {
        canBusOff(Handle1);
        canClose(Handle1);
        ComboBox5->Enabled = true;
        Button16->Caption = "Bus ON";
        Timer1->Enabled = false;//test present timer
    }
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button1Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    flagStratDiag = true;
    sendList();
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button2Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    if(CheckBox2->Checked == true)
    {
        flagStrat03Mode = true;
    }
    flagSecAccess = true;
    sendList();
}
//---------------------------------------------------------------------------


void __fastcall TForm1::ComboBox3Change(TObject *Sender)
{
    ComboBox4->ItemIndex = -1;
    ComboBox4->Text = "InputStatus";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ComboBox4Change(TObject *Sender)
{
    ComboBox3->ItemIndex = -1;
    ComboBox3->Text = "VehicleStatus";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button8Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    flagReadDTC = true;
    sendList();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::PageControl1Change(TObject *Sender)
{
    if (PageControl1->ActivePage == TabSheet1)
    {
        Button11->Caption = "ReadCanConfig";
        Button12->Caption = "WriteCanConfig";
    }
    if (PageControl1->ActivePage == TabSheet2)
    {
        Button11->Caption = "ReadVariantCode";
        Button12->Caption = "WriteVariantCode";
    }
}
//---------------------------------------------------------------------------




void __fastcall TForm1::Button3Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    if(CheckBox2->Checked == true)
    {
        flagStrat03Mode = true;
    }    
    flagReset = true;
    sendList();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button4Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    if(CheckBox2->Checked == true)
    {
        flagStrat03Mode = true;
        flagSecAccess = true;
    }
    flagStartRoutine = true;
    sendList();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button12Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    if(CheckBox2->Checked == true)
    {
        flagStrat03Mode = true;
        flagSecAccess = true;
    }
    flagWriteConfig = true;
    sendList();
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button5Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    if(CheckBox2->Checked == true)
    {
        flagStrat03Mode = true;
        flagSecAccess = true;
    }
    flagStopRoutine = true;
    sendList();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button6Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    if(CheckBox2->Checked == true)
    {
        flagStrat03Mode = true;
        flagSecAccess = true;
    }
    flagRoutineResult = true;
    sendList();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button7Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    flagStatusRead = true;
    sendList();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button9Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    flagSurported = true;
    sendList();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::button10Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    flagClearDTC = true;
    sendList();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button11Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    flagReadConfig = true;
    sendList();
}

//---------------------------------------------------------------------------


void __fastcall TForm1::Button13Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    if(CheckBox2->Checked == true)
    {
        flagStrat03Mode = true;
    }
    flagCtrlON = true;
    sendList();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button14Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    if(CheckBox2->Checked == true)
    {
        flagStrat03Mode = true;
    }
    flagCtrlOFF = true;
    sendList();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button15Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    if(CheckBox2->Checked == true)
    {
        flagStrat03Mode = true;
    }
    flagReturnECU = true;
    sendList();
}

//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton1Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton2Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton3Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton4Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton5Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton6Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";        
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton7Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";        
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton8Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";        
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton12Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";        
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton13Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";        
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton14Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";        
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton15Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";        
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton27Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";        
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton17Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "UP";
    Button14->Caption = "DOWN";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton18Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "UP";
    Button14->Caption = "DOWN";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton19Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "UP";
    Button14->Caption = "DOWN";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton20Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "UP";
    Button14->Caption = "DOWN";        
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton21Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "LOCK";
    Button14->Caption = "UNLCOK";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton22Click(TObject *Sender)
{
    Button14->Visible = false;
    Button13->Caption = "UNLOCK";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton23Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton24Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton28Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::RadioButton9Click(TObject *Sender)
{
    Button14->Visible = true;
    Button13->Caption = "ON";
    Button14->Caption = "OFF";
} 
//---------------------------------------------------------------------------
void __fastcall TForm1::Button17Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    if(ComboBox6->ItemIndex != -1)
    {
        if(CheckBox2->Checked == true)
        {
            flagStrat03Mode = true;
        }
        flagCommControl = true;
    }
    sendList();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button18Click(TObject *Sender)
{
    if(CheckBox3->Checked == true) Memo1->Clear();
    clearFlag();
    if(ComboBox7->ItemIndex != -1)
    {
        if(CheckBox2->Checked == true)
        {
            flagStrat03Mode = true;
        }
        flagDTCSetting = true;
    }
    sendList();  
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button19Click(TObject *Sender)
{
    Memo1->Clear();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button20Click(TObject *Sender)
{
    Memo1->SelectAll();
    Memo1->CopyToClipboard();
}
//---------------------------------------------------------------------------


void __fastcall TForm1::CheckBox2Click(TObject *Sender)
{
    if(CheckBox2->Checked == true)
    {
        CheckBox1->Enabled = false;
        CheckBox4->Enabled = false;
    }
    else if(CheckBox2->Checked == false)
    {
        CheckBox1->Enabled = true;
        CheckBox4->Enabled = true;
    }
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    //tester-present
    if((CheckBox1->Enabled == true) && (CheckBox1->Checked == true))
    {
        int stat;
        CanMessage messageTx = {0x740,
                                0x3,
                                0x02, 0x3E, 0x00};
        stat = canWrite(Handle1, 0x740, messageTx.data, 8, 0);
        if ((stat == canOK) && ((CheckBox4->Enabled == true) && (CheckBox4->Checked == true)))
        {
            Memo1->Lines->Add(">>>>>tester present<<<<<");
            memo1Display(&messageTx, 0);
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::CheckBox1Click(TObject *Sender)
{
    if(CheckBox1->Checked == false)
    {
        CheckBox4->Enabled = false;
    }
    else if(CheckBox1->Checked == true)
    {
        CheckBox4->Enabled = true;
    }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ComboBox2Change(TObject *Sender)
{
    if(ComboBox2->ItemIndex == 4) //battery saver
    {
        Button6->Enabled = false;
        Button5->Enabled = false;
    }
    else
    {
        Button6->Enabled = true;
        Button5->Enabled = true;
    }
}
//---------------------------------------------------------------------------




